/*******************************************************************************
* Copyright (C) 2014 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
/*============================================================================
 * 
 * Author(s): Maxim Integrated Products
 * Contributors:
 * Date:          
 * Purpose:       
 * Description:   EMV Level 1 library
 * 
 *==========================================================================*/
#ifndef _LIB_EMV_H_
#define _LIB_EMV_H_

#include <mml_sc.h>

/*--------------------------------------------------------------------------*/

/**
 * @defgroup LIBEMV1 EMV Level 1 library
 * @{
 */

/**
 *  
 * @defgroup EMV1_EVENT EMV event.
 * @ingroup LIB1EMV
 * 
 * @{
 * 
 */
/** \showinitializer This event indicator is raised when all the response of Answer To Reset 
 * has been received. This event IS NOT functional yet. Please DO NOT use it. */
#define EMV_EVENT_ATR_COMPLETED				0

/** \showinitializer This event indicator is raised when the Response APDU is received */
#define EMV_EVENT_DATA_RECEIVED				1

/** \showinitializer This event indicator is raised when all data has been sent */
#define EMV_EVENT_DATA_SENT                 2

/** \showinitializer This event indicator is raised when an error has occurred */
#define EMV_EVENT_ERROR                     3

/** \showinitializer Maximum number of EMV events. */
#define EMV_EVENT_COUNT             (EMV_EVENT_ERROR + 1)
/** @} */

/**
 *  
 * @defgroup EMV1_MODE EMV mode.
 * @ingroup LIB1EMV
 * 
 * @{
 * 
 */
/** \showinitializer Allow EMV library to handle PPS negotiation if needed. */
#define EMV_MODE_MANAGE_PPS         0x01
/** \showinitializer Allow EMV library to manage abortion with S(ABORT) response */
#define EMV_MODE_T1_MANAGE_ABORT    0x10
/** \showinitializer Allow EMV library not to deactivate directly after a timeout.  */
#define EMV_MODE_T1_MANAGE_TIMEOUT  0x20
/** \showinitializer Allow EMV library to manage re-synchronization. */
#define EMV_MODE_T1_MANAGE_RESYNC   0x40
/** \showinitializer Allow EMV library to handle IFSD negotiation if needed. */
#define EMV_MODE_T1_IFSD			0x80
/** @} */ 
/*----------------------------------------------------------------------------
 * Data and configuration structures
 *---------------------------------------------------------------------------*/
/**
 *
 * @defgroup EMV1_SLOT EMV slot.
 * @ingroup LIB1EMV
 *
 * @{
 *
 */

/** The configuration structure used to set up the Smart Card Interface */
typedef struct 
{

    
    /** \showinitializer Power supply. Possible values are :
     *  #N_MQ55_SC_POWER_1_8V
     *  #N_MQ55_SC_POWER_3V
     *  #N_MQ55_SC_POWER_5V
     */
    unsigned int power;
    
    /** \showinitializer Smart card protocol. Possible values are :
     *  #MQ55_SCPROTOCOL_T0
     *  #MQ55_SCPROTOCOL_T1
     */
    unsigned int protocol;
        
    /** \showinitializer Smart Card Clock Frequency. Possible values are #MQ55_SCCLOCK_EXTERNAL
     * or a combinaison between #MQ55_SCCLOCK_INTERNAL and
     *  #MQ55_SCCLOCK_4_8MHz
     *  #MQ55_SCCLOCK_3_2MHz
     *  #MQ55_SCCLOCK_3MHz
     *  #MQ55_SCCLOCK_2MHz
     */
    unsigned int clock;
    
    /** \showinitializer Possible values are an OR combinaison :
     *  #EMV_MODE_MANAGE_PPS
     *  #EMV_MODE_T1_MANAGE_RESYNC                   
     */
    unsigned int mode;
    /** \showinitializer Identifier of timer used 
        * hal_timer_dev0
        * hal_timer_dev1
        * hal_timer_dev2
        * hal_timer_dev3
        */
    unsigned int timernum;
    
} EMV_SLOT_CONFIG;

/** The structure used to retrieve or to set up the communication parameters */
typedef struct 
{         

    /** \showinitializer Speed communication (parameter TA1 of ISO 7816-3) */
    unsigned char FIDI;    

    /** \showinitializer Extra Guard Time (parameter TC1 or N of ISO 7816-3) */
    unsigned char EGT;  

    /**  \showinitializer
     * If protocol T=0 is selected, the parameter indicates the Waiting 
     * Integer (parameter TC2 of ISO 7816-3 - the default value is 10) 
     * If the protocol T=1 is selected, the parameter indicates the 
     * Block and Character Waiting Time Integer (parameter TB3 of ISO 7816-3) 
     */
    unsigned char WI;   

     /** \showinitializer If the protocol T=1 is selected, the parameter indicates the 
      * Waiting Time Extention (the default value is 1). */
    unsigned char WTX;    
     
    /** \showinitializer If the protocol T=1 is selected, the parameter indicates the computing 
     * mode for EDC : #MQ55_SCEDC_LRC or #MQ55_SCEDC_CRC (The default value
     * is an LRC) */ 
    unsigned char EDC;           
       
    /** \showinitializer The parameter indicates the selected protocol : 
     *  #MQ55_SCPROTOCOL_T0
     *  #MQ55_SCPROTOCOL_T1 */
    unsigned char protocol;
   
    /** \showinitializer The power supply value :
     *  #N_MQ55_SC_POWER_1_8V
     *  #N_MQ55_SC_POWER_3V
     *  #N_MQ55_SC_POWER_5V
     */
    unsigned char power;                   
           
    /** \showinitializer Convention used to transfer byte : 
     *  #MQ55_SCCONV_DIRECT
     *  #MQ55_SCCONV_INVERSE */
    unsigned char conv;  
    
    /** \showinitializer If the protocol T=1 is selected, the parameter indicates the Information
     * Field Size for the Card (parameter TA3 of ISO 7816-3). */
    unsigned char IFSC;
    /** \showinitializer Possibility to set Character Waiting Time */
    unsigned int cwt;
    /** \showinitializer Possibility to set Block Waiting Time */
    unsigned int bwt;
    
} emv_slot_info_t;

/** @} */

/*----------------------------------------------------------------------------
 * Function declarations
 *---------------------------------------------------------------------------*/
/**
 * @defgroup EMV_FUNC EMV Function interfaces
 * @ingroup LIBEMV1
 * @{
*/
#ifdef __cplusplus
extern "C" {
#endif

/**
 * The function initializes the EMV level 1 library and must be called before
 * any other library function.
 * 
 * @param[in] params   Pointer to an initialized configuration structure.
 *  
 * @retval #NO_ERROR			No error
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval #COMMON_ERR_ALREADY		This device is already initialized. Please call
 * 							#emv_shutdown() first.
 * @retval Other            See \link Error_Codes Error Codes \endlink
 * 							or #mq55_sc_init()'s error codes.
 * 
 */
int emv_init( EMV_SLOT_CONFIG *params );

/**
 * The function shutdowns the EMV level 1 library.
 *  
 * @retval #NO_ERROR			No error. Operation has been done properly;
 * 							or device has not been previously initialized.
 * @retval Other            See #mq55_sc_shutdown()'s error codes.
 * 
 */
int emv_shutdown(void);
 
/** 
 * The function provides the current state of a Smart Card Interface. 
 * It returns information indicating :
 *  \li The power supply value
 *  \li Card presence
 *  \li The card power status 
 *  \li The communication protocol (T=0 or T=1)
 * 
 * 
 * @param[out] status   Receives the current state of the Smart Card Interface. 
 *                      Upon success, it receives a combination of the following
 *                      state indicators: 
 *                        \li  #MQ55_SCSTATUS_POWER_5V
 *                        \li  #MQ55_SCSTATUS_POWER_3V
 *                        \li  #MQ55_SCSTATUS_CARD_NOT_POWERED
 *                        \li  #MQ55_SCSTATUS_CARD_POWERED
 *                        \li  #MQ55_SCSTATUS_CARD_NOT_INSERTED
 *                        \li  #MQ55_SCSTATUS_CARD_INSERTED
 *  
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval Other            See \link Error_Codes Error Codes \endlink
 * 							or #mq55_sc_get_status()'s error codes.
 * 
 */
int emv_get_status(int *status );

/** 
 * The function configures a Smart Card Interface and selects the working 
 * clock for the interface.
 * 
 * 
 * @param[in] params    	Pointer to an initialized configuration structure.
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval #COMMON_ERR_INVAL   	Invalid parameter.
 * @retval Other        	See #mq55_sc_set_config()'s error codes.
 * 
 */
int emv_set_config(EMV_SLOT_CONFIG *params );

/**
 * The function powers up and resets a card. During the card 
 * Answer To Reset (ATR), the function performs a check using EMV criteria. 
 * If the reset response is EMV-compliant, the communication settings are 
 * changed, else the card is rejected.  
 * 
 * 
 * @param[out] atr      Valid pointer to the card Answer To Reset (ATR).
 * 
 * @param[out] length   Valid pointer to the length of the Answer To Reset.
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval #COMMON_ERR_ALREADY     Operation already pending.
 * @retval #N_SCS_ERR_CARD_ABSENT     Card absent.
 * @retval #N_SCS_ERR_INVALID_ATR     Bad Answer To Reset.
 * @retval Other            See \link Error_Codes Error Codes \endlink
 * 							or #mq55_sc_power_up()'s ones and those from
 * 							synchronous treatment of activation.
 * 
 * @note The function is synchronous since a call to #emv_attach() makes 
 * the function asynchronous by returning immediately without waiting the end
 * of the operation. It's then up to #emv_power_up() caller to wait for ATR.
 * 
 */
int emv_power_up(unsigned char *atr, unsigned int *length );

/**
 * The function powers down a card.
 * 
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval Other            See #mq55_sc_power_down()'s error codes.
 * 
 */
int emv_power_down(void);

/**
 * The function is used to retreive the working communication parameters.
 * 
 * 
 * @param[out] slot_info    Valid pointer to an initialized #emv_slot_info_t
 *                          structure. 
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval Other            See \link Error_Codes Error Codes \endlink,
 * 							#mq55_sc_set_slot_info()'s and #mq55_sc_ioctl()'s
 * 							error codes.
 * 
 */
int emv_get_slot_info(emv_slot_info_t *slot_info );

/**
 * The function is used to set the working communication parameters.
 * 
 * 
 * @param[in] slot_info     Valid pointer to an initialized #emv_slot_info_t
 *                          structure.
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval Other            See #mq55_sc_set_slot_info()'s and #mq55_sc_ioctl()'s
 * 							error codes.
 * 
 */
int emv_set_slot_info(emv_slot_info_t *slot_info );


                           
/**
 * The function sends a command Application Protocol Data Unit (APDU) to a card, 
 * and retreives the response APDU, plus the status words SW1 SW2. 
 * 
 * The transportation of the APDU in T=0 protocol or T=1 protocol is done 
 * according to EMV criteria.
 * 
 * 
 * @param[in]   apdu		Valid pointer to the send buffer
 * @param[in]	apdu_length	APDU command length
 * @param[out]  response	Valid pointer to the card r_apdu
 * 
 * @param[in,out] response_length	Valid pointer to the size of r_apdu buffer, 
 *                          updated with the number of bytes available 
 *                          in the r_apdu buffer.
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP   Operation not supported. Device not initialized.
 * 							Use #emv_init() first.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval Other            See \link Error_Codes Error Codes \endlink
 * 							or those from synchronous treatment of communication.
 *
 * @note The function is synchronous since a call to #emv_attach() makes  
 * the function asynchronous by returning immediately without waiting the end
 * of the operation.
 * 
 */                        
int emv_transmit(unsigned char	*apdu,
						unsigned int	apdu_length, 
						unsigned char	*response, 
						unsigned int	*response_length);
          

/**
 * The function registers an interrupt handler for a type of event.
 *
 * @param[in] event     Event type. Possible values are the following: 
 *                          \li #EMV_EVENT_ATR_COMPLETED
 *                          \li #EMV_EVENT_DATA_RECEIVED
 *                          \li #EMV_EVENT_DATA_SENT
 *                          \li #EMV_EVENT_ERROR
 * 
 * @param[in] handler   Pointer to the interrupt handler function.
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP	Device number exists but not initialized.
 * 							This operation is then not supported by device.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * @retval #COMMON_ERR_ALREADY		A handler is already attached for this event,
 * 							please call #emv_detach() first.
 * 
 */
int emv_attach(int event, void (*handler)(int) );


/**
 * The function unregisters an interrupt handler that is used to process 
 * a particular event.
 *
 * @param[in] event      Event type. Possible values are the following: 
 *                          \li #EMV_EVENT_ATR_COMPLETED
 *                          \li #EMV_EVENT_DATA_RECEIVED
 *                          \li #EMV_EVENT_DATA_SENT
 *                          \li #EMV_EVENT_ERROR
 *  
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP	Device number exists but not initialized.
 * 							This operation is then not supported by device.
 * @retval #COMMON_ERR_INVAL       Invalid parameter
 *
 */
int emv_detach(int event );

/**
 * The function is used to cancel the current smart card transaction.
 *
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP	Device number exists but not initialized.
 * 							This operation is then not supported by device.
 * @retval Other            See #mq55_sc_cancel()'s error codes.
 *
 */
 int emv_cancel(void);


/**
 * The function is used to retrieve the last status error (useful with
 * asynchronous operations).
 *
 * @param[out]  err     Valid pointer to the last error. 
 * 
 * @retval #NO_ERROR			No error
 * @retval #N_SCS_ERR_DEV_NO_SUPP	Device number exists but not initialized.
 * 							This operation is then not supported by device.
 * @retval #COMMON_ERR_INVAL       Invalid parameter.
 * 
 */
int emv_get_last_error(int *err );

/** @} */


#ifdef __cplusplus
}
#endif /* C++ */

/** @} */

#endif /* _LIB_EMV_H_ */
